package Leo.security;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.social.security.SpringSocialConfigurer;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@Configuration
//@EnableWebSecurity//启动Security
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    AuthenticationProviderImpl provider;//注入我们自己的AuthenticationProvider

    @Autowired
    SpringSocialConfigurer springSocialConfigurer;

    @Autowired
    SystemProperties systemProperties;

    Logger log = LoggerFactory.getLogger(SecurityConfig.class);

    /**
     * 配置AuthenticationProvider
     *
     * @param auth
     * @throws Exception
     */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.authenticationProvider(provider);
        System.out.println("配置authenticationprovider");
//        auth
//        .inMemoryAuthentication()
//            .withUser("admin").password("123456").roles("USER")
//            .and()
//            .withUser("test").password("test123").roles("ADMIN");
    }


    @Override
    protected void configure(HttpSecurity http) throws Exception {
//        FormLoginConfigurer<HttpSecurity> httpSecurityFormLoginConfigurer1 = http.formLogin();
//        FormLoginConfigurer<HttpSecurity> httpSecurityFormLoginConfigurer = httpSecurityFormLoginConfigurer1.loginPage("/login");
//        HttpSecurity and = http.formLogin().loginPage("/login").and();
//        ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry expressionInterceptUrlRegistry = http.authorizeRequests();
//        http.httpBasic();//弹窗（跟Security的默认配置一样）

        //链式写法，作用跟上面一样
        log.debug("配置security信息");
        http.
                apply(springSocialConfigurer) //添加Social的配置
                .and().authorizeRequests()
                .antMatchers(systemProperties.LOGIN_URL,"/login","/index", "/info", "/base/**","/signup/**","/signin","/register","/socialinfo","/auth/**")//指定页面路径
                .permitAll()//允许所有人访问（不理会是否有登录）
                .antMatchers("/me")//指定页面路径
                .hasAnyRole("MEMBER", "SUPER_ADMIN")//个人首页只允许拥有MENBER,SUPER_ADMIN角色的用户访问
                .anyRequest()//除上面以外的其他任何请求
                .authenticated()//都允许登录后的人员访问
                .and()//重新获取httpSecurity对象
                .formLogin()//切换到设置login
                .loginPage(systemProperties.LOGIN_URL) //设置为controller
//                .loginPage("/login")//这里程序默认路径就是登陆页面,可以设置是html页面，也可以是controller
                .permitAll()//，允许所有人进行登陆
                .loginProcessingUrl(systemProperties.LOGIN_PROCESS_URL)//登陆提交的处理url
                .failureForwardUrl("/errorpage")//登陆失败进行转发，这里回到登陆页面，参数error可以告知登陆状态
                .defaultSuccessUrl("/index")//登陆成功的默认url，这里去到个人首页。意思是，直接输入登录url后，点击登录后才跳转到default值。如果是在其他URL跳转到登录界面，登陆后还是会跳到原来的URL
                /**
                 * 除了设置default值外，可以使用另一种方式：successHandler，这是登录成功后的处理，做这个处理的话，就会
                 * 导致defaultSuccessUrl失效
                 */
                .successHandler(new AuthenticationSuccessHandler() {//登陆成功后的一些处理
                    @Override
                    public void onAuthenticationSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException {
                        System.out.println("登录成功，需要写入session吗？");
                        boolean b = authentication.getPrincipal() instanceof UserDetailsImpl;
                        System.out.println(b);
                    }
                })
                .and()//重新获取httpSecurity对象
                .logout()//切换到设置logout
                .logoutUrl("/logout").permitAll()
                .logoutSuccessUrl("/?logout=true")//按顺序，第一个是登出的url，security会拦截这个url进行处理，所以登出不需要我们实现，第二个是登出url，logout告知登陆状态
                .and()//重新获取httpSecurity对象
                .rememberMe()//切换到设置rememberMe
                .tokenValiditySeconds(604800)//记住我功能，cookies有限期是一周
                .rememberMeParameter("remember-me")//登陆时是否激活记住我功能的参数名字，在登陆页面有展示
                .rememberMeCookieName("workspace")//cookies的名字，登陆后可以通过浏览器查看cookies名字

                .and().csrf().disable();  //暂时禁掉跨域限制
    }

//    @Autowired
//    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
//        auth.inMemoryAuthentication()
//                .withUser("admin").password("123456").roles("USER");
//    }

}
